﻿using System.Windows;
using System.Windows.Controls;
using Microsoft.Win32;
using FNN.Networks;
using FNN.NetworkMasters;
using FNN.Helpers;
using FNN.SourcePoints;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.IO;
using System;

namespace GraphicFNN.Pages
{
    /// <summary>
    /// Логика взаимодействия для TrainingPage.xaml
    /// </summary>
    public partial class TrainingPage : Page
    {
        public SerializationHelper serializationHelper = new SerializationHelper();

        public TrainingPage()
        {
            InitializeComponent();
        }

        protected List<SourcePoint> GetDataSource(string pathToData)
        {
            CsvHelper csvHelper = null;

            switch ((NetworkMastersList)CmbType.SelectedIndex)
            {
                case NetworkMastersList.Financial:
                    csvHelper = new FinancialCsvHelper(pathToData);
                    break;
                case NetworkMastersList.Regular:
                    csvHelper = new RegularCsvHelper(pathToData);
                    break;
            }

            if (csvHelper == null) return null;

            var initialData = csvHelper.GetBody();
            var dataHeaders = csvHelper.GetHeader();
            var result = csvHelper.ProcessData(dataHeaders, initialData);

            return result;
        }

        protected List<DateSourcePoint> GetFinancialDataSource(string pathToData)
        {
            var csvHelper = new FinancialCsvHelper(pathToData);
            var initialData = csvHelper.GetBody();
            var dataHeaders = csvHelper.GetHeader();
            var tempList = csvHelper.ProcessData(dataHeaders, initialData);
            List<DateSourcePoint> result = new List<DateSourcePoint>();

            foreach (var point in tempList)
            {
                result.Add((DateSourcePoint)point);
            }

            return result;
        }

        private void BtnStartTraining_OnClick(object sender, RoutedEventArgs e)
        {
            Network targetNetwork = null;
            NetworkMaster netMaster = null;
            ChartWindow chartWindow = new ChartWindow();
            var currentDataSource = GetDataSource(TxtSourcePath.Text);

            switch ((NetworkMastersList)CmbType.SelectedIndex)
            {
                case NetworkMastersList.Financial:
                    netMaster = new FinancialNetworkMaster { PopulationCount = 3 };
                    ((FinancialNetworkMaster)netMaster).IterationResultsImproved += chartWindow.CatchResultsImproved;
                    ((FinancialNetworkMaster)netMaster).IterationChanged += chartWindow.CatchIterationChanged;
                    ((FinancialNetworkMaster)netMaster).DataSource = currentDataSource;
                    targetNetwork = (FinancialNetwork)serializationHelper.LoadBinary(TxtNetworkPath.Text);
                    ((FinancialNetworkMaster)netMaster).ProfitPercent = Convert.ToInt32(TxtResultPercent.Text);
                    break;
                case NetworkMastersList.Regular:
                    netMaster = new RegularNetworkMaster { PopulationCount = 3 };
                    ((RegularNetworkMaster)netMaster).IterationResultsImproved += chartWindow.CatchResultsImproved;
                    ((RegularNetworkMaster)netMaster).IterationChanged += chartWindow.CatchIterationChanged;
                    ((RegularNetworkMaster)netMaster).DataSource = currentDataSource;
                    targetNetwork = (RegularNetwork)serializationHelper.LoadBinary(TxtNetworkPath.Text);
                    ((RegularNetworkMaster)netMaster).NeededErrorRate = Convert.ToDouble(TxtResultPercent.Text.Replace(",", "."));
                    break;
            }

            if ((netMaster == null) || (targetNetwork == null))
            {
                MessageBox.Show("Ошибка! Файл поврежден или имел неверный формат!");
                return;
            }
            netMaster.IterationsLimit = Convert.ToInt32(TxtIterations.Text);
            netMaster.TimeLimit = Convert.ToInt32(TxtTime.Text);
            chartWindow.Show();

            var backgroundTask = Task.Factory.StartNew(() =>
            {
                var targetName = "";
                var targetPath = "";
                var serializationHelper = new SerializationHelper();

                var resultNetwork = netMaster.TrainMultiNetwork(targetNetwork);

                Dispatcher.Invoke(() =>
                {
                    targetName = targetNetwork.NetworkName;
                    targetPath = TxtNetworkPath.Text;
                    serializationHelper.WriteBinary(resultNetwork, targetPath);
                    chartWindow.Close();
                });
            });
        }

        private void BtnBrowseFile_OnClick(object sender, RoutedEventArgs e)
        {
            var fileBrowser = new OpenFileDialog()
            {
                CheckFileExists = true,
                Multiselect = false,
                Filter = "FNN|*.fnn|XML|*.xml|SOAP|*.soap"
            };
            fileBrowser.ShowDialog();
            TxtNetworkPath.Text = fileBrowser.FileName;
        }

        private void BtnBrowseSource_OnClick(object sender, RoutedEventArgs e)
        {
            var fileBrowser = new OpenFileDialog()
            {
                CheckFileExists = true,
                Multiselect = false,
                Filter = "CSV|*.csv"
            };
            fileBrowser.ShowDialog();
            TxtSourcePath.Text = fileBrowser.FileName;
        }
    }
}
